package com.zckj.jcServer;


import java.net.InetSocketAddress;

import com.zckj.handle.MonitorBYJCDecoder;
import com.zckj.handle.MonitorBYJCEncoder;
import com.zckj.util.Constant;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

/**
 * 集创数据采集tcp服务
 * @author ZCKJ
 *
 */
public class JCNServer {
	
	/**
	 * 
	 * @param port 服务端口
	 */
	public void bind(int port){
		//配置nio线程组
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		
		try {
			ServerBootstrap bootstrap = new ServerBootstrap();
			bootstrap.group(bossGroup, workerGroup)
				.channel(NioServerSocketChannel.class)
				.handler(new LoggingHandler(LogLevel.ERROR))
				.childHandler(new ChildChannelHandler())
				.option(ChannelOption.SO_BACKLOG, 1024)
				.option(ChannelOption.SO_KEEPALIVE, true)
				.option(ChannelOption.CONNECT_TIMEOUT_MILLIS,3000)
				.localAddress(new InetSocketAddress(port));
				//option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChildChannelHandle());
			
			//绑定端口， 同步等待绑定成功
			ChannelFuture future = bootstrap.bind(port).sync();
			
			//等待服务端监听端口关闭
			future.channel().closeFuture().sync();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally {
			//优雅退出，释放资源
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}
	}


	/**
	 * 网络事件处理器
	 */
	private class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
		@Override
		protected void initChannel(SocketChannel ch) throws Exception {
			// 添加自定义协议的编解码工具
			ch.pipeline().addLast(new MonitorBYJCEncoder());
			ch.pipeline().addLast(new MonitorBYJCDecoder());
			// 处理网络IO
			ch.pipeline().addLast(new ServerHandle());
		}
	}

	public static void main(String[] args) {
		int port = Integer.parseInt(Constant.PORT);
		
		if(args != null && args.length > 0){
			try {
				port = Integer.valueOf(args[0]);
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
		}
		new JCNServer().bind(port);
	}
}
